﻿// header.h: 标准系统包含文件的包含文件，
// 或特定于项目的包含文件
//
#pragma once

#if defined _M_IX86
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*'\"")
#elif defined _M_X64
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='amd64' publicKeyToken='6595b64144ccf1df' language='*'\"")
#else
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
#endif

//仅VS下编译有效,用GCC不行，GCC用清单文件

#include "targetver.h"
#define WIN32_LEAN_AND_MEAN             // 从 Windows 头文件中排除极少使用的内容
// Windows 头文件
#include <windows.h>
#include <CommCtrl.h>
#include <windowsx.h>
// C 运行时头文件
#include <stdlib.h>
#include <malloc.h>
#include <memory.h>
#include <tchar.h>

#include <cstring>
#include <ctime>
#include <iostream>

HFONT SimpleFont(const TCHAR* szFontName, int iSize, bool B) {
	return CreateFont(iSize, 0, 0, 0, B ? 700 : 400
		, FALSE //斜体
		, FALSE //下划线
		, FALSE, DEFAULT_CHARSET, OUT_CHARACTER_PRECIS,
		CLIP_DEFAULT_PRECIS,
		DEFAULT_QUALITY,
		VARIABLE_PITCH, szFontName);
}

HFONT SimpleFont(const TCHAR* szFontName, int iSize, bool B, bool I, bool U) {
	return CreateFont(iSize, 0, 0, 0, B ? 700 : 400
		, I //斜体
		, U //下划线
		, FALSE, DEFAULT_CHARSET, OUT_CHARACTER_PRECIS,
		CLIP_DEFAULT_PRECIS,
		DEFAULT_QUALITY,
		VARIABLE_PITCH, szFontName);
}

int DpiAware(double* iSc) {
	if (iSc != NULL) *iSc = 1;
	int rId = 0;
	HINSTANCE hLib = LoadLibrary(L"Shcore.dll");
	HINSTANCE hLib2 = LoadLibrary(L"user32.dll");
	if (hLib2 == NULL || hLib == NULL) {
		rId = 1;
	}
	typedef UINT(WINAPI* PFNDPI) (int);
	typedef UINT(WINAPI* PFNGET) ();

	PFNDPI pfnDpi = (PFNDPI)GetProcAddress(hLib, "SetProcessDpiAwareness");
	if (pfnDpi != NULL) {
		pfnDpi(1);
	}
	else rId = 2;
	PFNGET pfnGet = (PFNGET)GetProcAddress(hLib2, "GetDpiForSystem");
	if (pfnGet != NULL) {
		int get = pfnGet();
		if (iSc != NULL) *iSc = get / 96.0;
	}
	else rId += 3;
	FreeLibrary(hLib);
	FreeLibrary(hLib2);
	return rId;
}

int CALLBACK EnumFontFamExProc(ENUMLOGFONTEXW* lpelfe, NEWTEXTMETRICEX* lpntm, DWORD FontType, LPARAM lParam);
// 主要函数：填充ComboBox
void PopulateFontComboBox(HWND hWndComboBox)
{
	HDC hdc = GetDC(NULL); // 获取屏幕设备上下文
	if (hdc == NULL) {
		// 错误处理
		return;
	}

	LOGFONTW lf = { 0 };
	lf.lfCharSet = DEFAULT_CHARSET; // 枚举所有字符集的字体

	// 开始枚举字体
	EnumFontFamiliesExW(hdc, &lf, (FONTENUMPROCW)EnumFontFamExProc, (LPARAM)hWndComboBox, 0);

	ReleaseDC(NULL, hdc); // 释放设备上下文

	// 可选：设置默认选中项，例如第一项
	if (SendMessage(hWndComboBox, CB_GETCOUNT, 0, 0) > 0) {
		SendMessage(hWndComboBox, CB_SETCURSEL, 0, 0);
	}
}
// 假设有一个全局变量或方式来存储已添加的字体名以避免重复，例如使用哈希表或链表
// 这里为了示例，我们使用一个简单的全局链表（实际应用中应考虑更高效的数据结构）
// 注意：实际项目中需自行实现链表管理或使用更合适的数据结构

#define MAX_FONT_NAME 128
typedef struct FontNameNode {
	WCHAR fontName[MAX_FONT_NAME];
	struct FontNameNode* next;
} FontNameNode;

FontNameNode* gFontList = NULL; // 全局变量，存储已添加的字体名

// 检查字体名是否已存在于链表中
BOOL IsFontInList(const WCHAR* fontName) {
	FontNameNode* current = gFontList;
	while (current != NULL) {
		if (wcscmp(current->fontName, fontName) == 0) {
			return TRUE; // 找到重复项
		}
		current = current->next;
	}
	return FALSE; // 未找到
}

// 将字体名添加到链表
void AddFontToList(const WCHAR* fontName) {
	if (IsFontInList(fontName)) {
		return; // 已存在，不添加
	}
	FontNameNode* newNode = (FontNameNode*)malloc(sizeof(FontNameNode));
	if (newNode == NULL) return; // 内存分配失败
	wcscpy_s(newNode->fontName, MAX_FONT_NAME, fontName);
	newNode->next = gFontList;
	gFontList = newNode;
}

// 释放链表内存的函数（应在枚举结束后调用）
void FreeFontList() {
	FontNameNode* current = gFontList;
	while (current != NULL) {
		FontNameNode* temp = current;
		current = current->next;
		free(temp);
	}
	gFontList = NULL;
}

int CALLBACK EnumFontFamExProc(ENUMLOGFONTEXW* lpelfe, NEWTEXTMETRICEX* lpntm, DWORD FontType, LPARAM lParam) {
	HWND hCombo = (HWND)lParam;
	if (hCombo == NULL) {
		return 0;
	}

	// 检查字体名称是否以'@'开头
	if (lpelfe->elfFullName[0] == L'@') {
		return 1; // 跳过该字体，继续枚举
	}

	// 检查字体名称是否已存在（去重）
	if (IsFontInList(lpelfe->elfFullName)) {
		return 1; // 跳过重复项，继续枚举
	}

	// 将字体名称添加到链表
	AddFontToList(lpelfe->elfFullName);

	// 将字体名称添加到ComboBox
	SendMessageW(hCombo, CB_ADDSTRING, 0, (LPARAM)lpelfe->elfFullName);

	return 1; // 继续枚举
}

// 在调用枚举函数之后，记得调用 FreeFontList 来释放链表内存

#define WM_AUTOSIZE WM_USER
#define WM_RELOAD	WM_USER+1